from fastapi import APIRouter, Depends, status as http_status, Response
from customer.customer import verify_customer_token
from schemas.customer import CustomerModel
from utils.response import HTTPException
from users.users import verify_token
from schemas.users import UserModel
from db import get_db, crud, models
from sqlalchemy.orm import Session
from typing import Optional, List
from datetime import datetime
from schemas.article import ArticleModel, CreateArticleRequest, ArticlePagination, \
    UpdateArticleRequest, DeleteArticleRequest, CreateArticleCommentRequest, \
    ArticleCommentItem, LikeArticleCommentRequest, LikeArticleRequest

router = APIRouter(prefix="/article", tags=["文章管理"])


@router.post("", response_model=ArticleModel, response_model_exclude_none=True)
def create_article(data: CreateArticleRequest, user: UserModel = Depends(verify_token), db: Session = Depends(get_db)):
    data.created_on = datetime.now()
    data.created_by = user.id
    return crud.Article.create(db, data)


@router.get("", dependencies=[Depends(verify_token)],
            response_model=ArticlePagination, response_model_exclude_none=True)
def get_article_pagination(page: int, page_size: int, kw: Optional[str] = None, db: Session = Depends(get_db)):
    try:
        total, data = crud.Article.gets(db, page - 1, page_size, kw)
        return ArticlePagination(
            page=page,
            page_size=page_size,
            total=total,
            data=data
        )
    except Exception as err:
        raise HTTPException(status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR, message=str(err))


@router.get("/list", response_model=ArticlePagination, response_model_exclude_none=True)
def get_article_list(page: int, page_size: int, kw: Optional[str] = None, db: Session = Depends(get_db)):
    try:
        total, data = crud.Article.gets(db, page - 1, page_size, kw)

        article_list = []

        for item in data:
            article = ArticleModel.from_orm(item)
            article.comments_count = crud.ArticleComment.count_by_article(db, article.id)
            article_list.append(article)

        return ArticlePagination(
            page=page,
            page_size=page_size,
            total=total,
            data=article_list
        )
    except Exception as err:
        raise HTTPException(status_code=http_status.HTTP_500_INTERNAL_SERVER_ERROR, message=str(err))


@router.put("",
            response_model_exclude_none=True)
def update_article(data: UpdateArticleRequest, user: UserModel = Depends(verify_token), db: Session = Depends(get_db)):
    data.updated_by = user.id
    data.updated_on = datetime.now()
    crud.Article.update(db, data)
    return Response()


@router.get("/detail/{article_id}", response_model=ArticleModel, response_model_exclude_none=True)
def get_article_detail(article_id: int, db: Session = Depends(get_db)):
    article = crud.Article.get(db, article_id)
    if article is not None:
        article.views_count += 1
        db.commit()
        return article
    raise HTTPException(status_code=404)


@router.delete("/{article_id}", dependencies=[Depends(verify_token)], response_model_exclude_none=True)
def delete_article(article_id: int, user: UserModel = Depends(verify_token), db: Session = Depends(get_db)):
    crud.Article.delete(db, DeleteArticleRequest(
        id=article_id,
        updated_on=datetime.now(),
        updated_by=user.id
    ))
    return Response()


# 文章点赞
@router.post("/like/{article_id}")
def like_article(article_id: int,
                 customer: CustomerModel = Depends(verify_customer_token),
                 db: Session = Depends(get_db)):
    article = crud.Article.get(db, article_id)
    if article is not None:
        article.likes_count += 1

        crud.ArticleLike.create(db, article_id, customer.id)

        db.commit()

    raise HTTPException(status_code=404)


# 文章评论
@router.post("/comment")
def add_article_comment(data: CreateArticleCommentRequest,
                        customer: CustomerModel = Depends(verify_customer_token),
                        db: Session = Depends(get_db)):
    data.customer_id = customer.id
    return crud.ArticleComment.create(db, data)


@router.get("/{article_id}/comment")
def get_article_comment(article_id: int, db: Session = Depends(get_db)):
    comment_list = crud.ArticleComment.get_by_article_id(db, article_id)

    result: List[ArticleCommentItem] = []

    for comment in comment_list:
        result.append(ArticleCommentItem(
            id=comment.id,
            customer_id=comment.customer_id,
            parent_id=comment.parent_id,
            likes_count=comment.likes_count,
            avatar=comment.customer.avatar,
            nickname=comment.customer.nickname,
            content=comment.content,
            created_on=comment.created_on
        ))

    return result


@router.post("/comment/like")
def article_comment_like(data: LikeArticleCommentRequest,
                         customer: CustomerModel = Depends(verify_customer_token),
                         db: Session = Depends(get_db)):
    data.customer_id = customer.id
    if data.is_like:
        crud.ArticleComment.add_like(db, data.comment_id)
        crud.ArticleCommentLike.create(db, data)
    else:
        crud.ArticleComment.subtract_like(db, data.comment_id)
        crud.ArticleCommentLike.delete(db, customer.id, data.comment_id)
    return Response()


@router.post("/like")
def article_like(data: LikeArticleRequest,
                 customer: CustomerModel = Depends(verify_customer_token),
                 db: Session = Depends(get_db)):
    data.customer_id = customer.id
    if data.is_like:
        crud.Article.add_like(db, data.article_id)
        crud.ArticleLike.create(db, customer.id, data.article_id)
    else:
        crud.Article.subtract_like(db, data.article_id)
        crud.ArticleLike.delete(db, customer.id, data.article_id)
    return Response()


@router.get("/stats")
def stats(db: Session = Depends(get_db)):
    data = db.query(
        models.Article.id,
        models.Article.title,
        models.Article.created_on,
        models.Article.views_count,
        models.Article.likes_count
    ).filter_by(status=1).all()

    return [
        {
            "id": item.id,
            "title": item.title,
            "created_on": item.created_on,
            "views_count": item.views_count,
            "likes_count": item.likes_count,
        } for item in data
    ]
